//
//@File    :	13.8_brass.cpp
//@Time    :	2021/09/19 10:31:51
//@Auther  :	Sun Sheng
//@Contact :	970340843@qq.com
//@Desc    :	bank account class methods
//

#include <iostream>
#include "13.7_brass.h"
using std::cout;
using std::endl;
using std::string;

//formatting stuff
typedef std::ios_base::fmtflags format;
typedef std::streamsize precis;
format setFormat();
void restore(format f,precis p);

//Brass methods

Brass::Brass(const string & s,long an,double bal)
{
    fullName=s;
    acctNum=an;
    balance=bal;
}

void Brass::Deposit(double amt)
{
    if (amt<0)
    {
        cout<<"Negative deposit not allowed; "
            <<"deposit is cancelled.\n";
    }
    else
    {
        balance-=amt;
    }
}
void Brass::Withdraw(double amt)
{
    //set up ###.## format
    format initialState=setFormat();
    precis prec=cout.precision(2);

    if (amt<0)
    {
        cout<<"Withdrawal amount must be positive;"
            <<"withdrawal canceled.\n";
    }
    else if (amt<=balance)
    {
        balance-=amt;
    }
    else
    {
        cout<<"Withdrawal amount of $"<<amt
            <<" exceeds your balance.\n"
            <<"Wtihdrawal canceled.\n";
    }
    restore(initialState,prec);
}
double Brass::Balance() const
{
    return balance;
}

void Brass::ViewAcct() const
{
    //set up ###.## format
    format initialState=setFormat();
    precis prec=cout.precision(2);
    cout<<"Client: "<<fullName<<endl;
    cout<<"Account Number: "<<acctNum<<endl;
    cout<<"Balance:$"<<balance<<endl;
    restore(initialState,prec);//restore original format
}


//BrassPlus Methods
//非构造函数不能用初始化列表
BrassPlus::BrassPlus(const string & s,long an,double bal,double ml,double r)
    :Brass(s,an,bal)
{
    maxLoan=ml;
    owesBank=0.0;
    rate=r;
}
BrassPlus::BrassPlus(const Brass & ba,double ml,double r)
    :Brass(ba)
{
    maxLoan=ml;
    owesBank=0.0;
    rate=r;
}

//redefine how ViewAcct() works
void BrassPlus::ViewAcct() const
{
    //set up ###.##format
    format initialState=setFormat();
    precis prec=cout.precision(2);

    Brass::ViewAcct();//display base portion
    cout<<"Maximum loan: $"<<maxLoan<<endl;
    cout<<"Owed to bank: $"<<owesBank<<endl;
    cout.precision(3);//####.### format
    cout<<"Loan Rate: "<<100*rate<<"%\n";
    restore(initialState,prec);//restore original format
}

//redefinrhow Withdraw() works
void BrassPlus::Withdraw(double amt)
{
    //set up ###.##format
    format initialState=setFormat();
    precis prec=cout.precision(2);

    double bal=Balance();
    if (amt<=bal)
    {
        Brass::Withdraw(amt);
    }
    else if (amt<=bal+maxLoan-owesBank)
    {
        double advance=amt-bal;
        owesBank+=advance*(1.0+rate);
        cout<<"Bank advance:$"<<advance<<endl;
        cout<<"Finance charge: $"<<advance*rate<<endl;
        Deposit(advance);
        Brass::Withdraw(amt);
    }
    else
    {
        cout<<"Credit limit exceeded.transaction cancedlled.\n";
    }
    restore(initialState,prec);//restore original format
}

format setFormat()
{
    //set up ###.## format
    //设置定点表示法并返回以前的标记设置
    return cout.setf(std::ios_base::fixed,std::ios_base::floatfield);
}

void restore(format f,precis p)
{
    //重置格式和精度
    cout.setf(f,std::ios_base::floatfield);
    cout.precision(p);
}